/***
 * * PROJECT
 * *    ATaG
 * * VERSION
 * *    $Revision: 1.1 $
 * * DATE
 * *    $Date: 2007/02/02 11:23:59 $
 * * LOG
 * *    $Log: TrafficTopologyGenerator.java,v $
 * *    Revision 1.1  2007/02/02 11:23:59  lmottola
 * *    Benchmarking code for compiler in.
 * *
 * * 
 * *   ATaG (Abstract Task Graph) - Data-driven Macroprogramming for
 * *                                Sensor Networks
 * *
 * *
 * *   This program is free software; you can redistribute it and/or
 * *   modify it under the terms of the GNU General Public License
 * *   as published by the Free Software Foundation; either version 2
 * *   of the License, or (at your option) any later version.
 * *
 * *   This program is distributed in the hope that it will be useful,
 * *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 * *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * *   GNU General Public License for more details.
 * *
 * *   You should have received a copy of the GNU General Public License
 * *   along with this program; if not, you may find a copy at the FSF web
 * *   site at 'www.gnu.org' or 'www.fsf.org', or you may write to the
 * *   Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * *   Boston, MA  02111-1307, USA
 ***/

package atag.apps.traffic;

import java.util.LinkedList;
import java.util.List;
import java.util.Random;

public class TrafficTopologyGenerator {

	public static final int COMM_RANGE = 620;

	public static final int SENSE_RANGE = 310;

	public static final int LANE_SPACE = 40;

	public static final int HS_SPACING = 8000;

	public static final int SIM_AREA = 24000;

	public static final int HS_NUMBER = 3;

	public static final int NODES_RAMP = 4;

	public static final int N_LANES = 4;

	private static final int RANDOM_SEED = 12345;

	private static int nextNodeId;

	public static List<String> generateTopology(int commRange, int senseRange,
			int laneSpace, int hsSpacing, int hsNumber, int nodesRamp,
			int nLanes, int simArea) {

		nextNodeId = 0;
		LinkedList<String> nodes = new LinkedList<String>();

		int routingNodeSpacing = (int) Math.sqrt(0.6 * commRange * commRange
				+ nLanes * laneSpace);

		// Generating routing nodes
		for (int i = 0; i < simArea; i += routingNodeSpacing) {
			String routingNode = nextNodeId + " 0 " + i
					+ " HS:0 attachedSensors:none\n";
			nodes.add(routingNode);
			nextNodeId++;
		}

		// Generating HSs
		for (int i = 0; i < hsNumber; i++) {
			buildHS(nodes, commRange, i, hsSpacing, nLanes, laneSpace,
					nodesRamp, i * hsSpacing);
		}

		nodes.addFirst(nextNodeId + " " + simArea + " " + simArea + " "
				+ commRange + " " + senseRange + "\n");
		return nodes;
	}

	private static void buildHS(LinkedList<String> nodes, int commRange,
			int HSid, int HSspacing, int nLanes, int laneSpacing,
			int nodesOnRamp, int startingY) {

		Random rnd = new Random(RANDOM_SEED);

		try {
			// Creating SpeedSampler tasks
			for (int i = 0; i < nLanes; i++) {

				// Generating random position within this HS and lane
				int x = i * laneSpacing + laneSpacing / 2;
				int y = startingY + rnd.nextInt(HSspacing);
				String speedSampler = nextNodeId + " " + x + " " + y + " HS:"
						+ HSid + " attachedSensors:SpeedSensor\n";
				nodes.add(speedSampler);
				nextNodeId++;
			}

			// Creating RampSampler tasks
			for (int i = 0; i < nodesOnRamp; i++) {

				// Generating position
				int x = (nLanes + i) * laneSpacing;
				int y = startingY + (HSspacing / 2) - (i * commRange / 2); // Arbitrary
				String rampSampler = nextNodeId + " " + x + " " + y + " HS:"
						+ HSid + " attachedSensors:PresenceSensor\n";
				nodes.add(rampSampler);
				nextNodeId++;
			}

			// Creating SpeedLimitDisplayer
			String slDisplay = nextNodeId + " 0 " + (startingY + HSspacing)
					+ " HS:" + HSid + " attachedActuators:SpeedLimitDisplay\n";
			nodes.add(slDisplay);
			nextNodeId++;

			// Creating RGSignalDisplayer
			String rgDisplay = nextNodeId + " " + (nLanes * laneSpacing) + " "
					+ (startingY + HSspacing) + " HS:" + HSid
					+ " attachedActuators:RampSignal\n";
			nodes.add(rgDisplay);

			nextNodeId++;
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}
